package funcref;

import java.util.Objects;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;

import org.junit.jupiter.api.Test;

public class FuncRefDemo {
	/**
	 * interface Supplier<T>{
	 *     T get();  
	 * }
	 * 
	 * interface Consumer<T>{
	 * 	   void accept(T t);
	 * }
	 * 
	 * interface Function<T,R>{
	 *     R  apply(T t);  // static double sqrt(double );
	 * }
	 * 
	 * interface Predicate<T>{
	 *     boolean test(T t);  // boolean Objects.isNull(obj)
	 * }
	 */
	interface MyString{
	    String mySubString(String s, int x, int y);
	}
	
	interface MyIf{
		char dealWith(String str,int index);
	}
	
	
	interface Maker<T,R,Q>{
		T make(R r,Q q);
	}
	class Person{
		String name;
		int age;
		public Person(String name, int age) {
			this.name = name;
			this.age = age;
		}
	}
	
	@Test
	public void constructorFunRef() {
		//  类名::new;
		Maker<Person,String,Integer> maker = Person::new;
		Person p = maker.make("张三", 20);
		
		System.out.println(p.name);
		System.out.println(p.age);
	}
	
	@Test
	public void specialFunRef() {
		//            类名::非静态方法名   接口的第个参数.非静态方法名()
		MyString con = String::substring;
		String str = con.mySubString("hello world", 2, 8); // "hello world".substring(2,8)
		System.out.println(str);
		
		MyIf  mf = String::charAt;
		char c = mf.dealWith("hello", 3);  // "hello".charAt(3)
		System.out.println(c);
	}
	
	@Test
	public void autoFunRef() {
		//  对象::非静态方法名
		Supplier<String> fun1 = "hello kitty"::toUpperCase;
		System.out.println(fun1.get());  // "hello kitty".toUpperCase();
		
		Function<Integer,String> fun2 = "hello kitty"::substring;
		System.out.println(fun2.apply(3)); // "hello kitty".substring(3);
		
		Predicate<String> pre = "hello"::equals;
		System.out.println(pre.test("hello4"));  // "hello".equals("hello")
		
		Supplier<Boolean> sup = "hello"::isEmpty;
		System.out.println(sup.get());  // "hello".isEmpty();
	}
	
	@Test
	public void staticFunRef() {
		                              //::作用域符号 类名::静态方法名;
		Function<Double,Double> fun1 = Math::sqrt;
		System.out.println(fun1.apply(16.0));  // Math.sqrt(16.0)
		
		Function<Character,Boolean> fun2 = Character::isDigit;
		System.out.println(fun2.apply('a'));  //Character.isDigit('a')
		
		Predicate<Object> pre = Objects::isNull;
		System.out.println(pre.test(null));  // Objects.isNull(null);
	}
}
